import hashlib
from enum import Enum
import re
from . import exceptions
from datetime import datetime

class PurchaseStatus(str, Enum):
    UNAUDITED = 'unaudited'
    AUDITED = 'audited'
    CANCELLED = 'cancelled'
    RECEIVED = 'received'

    @property
    def description(self):
        descriptions = {
            'unaudited': '待审核',
            'audited': '已审核',
            'received': '已入库',
        }
        return descriptions.get(self.value, '')

class SaleStatus(str, Enum):
    UNPAID = 'unpaid'
    CANCELLED = 'cancelled'
    PAID = 'paid'

    @property
    def description(self):
        descriptions = {
            'unpaid': '待付款',
            'cancelled': '已取消',
            'paid': '已付款'
        }
        return descriptions.get(self.value, '')

class UserRole(str, Enum):
    ADMIN = 'admin'
    MANAGER = 'manager'
    SALER = 'saler'

    @property
    def description(self):
        descriptions = {
            'admin': '管理员',
            'manager': '经理',
            'saler': '销售员'
        }
        return descriptions.get(self.value, '')
    
class PaymentMethod(str, Enum):
    CASH = 'cash'
    WECHAT = 'wechat'
    ALIPAY = 'alipay'
    
    @property
    def description(self):
        descriptions = {
            'cash': '现金',
            'wechat': '微信',
            'alipay': '支付宝'
        }
        return descriptions.get(self.value, '')
    
WEEKDAYS = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"]

def string_to_bool(string, return_none = False):
    if isinstance(string, str):
        string = string.lower()
    if string in ['true', '1', 'yes', 't', 'y', 1, True]:
        return True
    if string in ['false', '0', 'no', 'f', 'n', 0, False]:
        return False
    if return_none:
        return None
    raise exceptions.ErrorException("非布尔值字符串")

def parse_category_tree(categories, top_category = {0: {"id": 0, "name": "全部分类", "parent_id": None}}):
    category_tree = top_category
    for category in categories:
        category_tree[category["id"]] = {
            'id': category["id"],
            'name': category["name"],
            'parent_id': category["parent_id"],
        }
    return category_tree

START_SEED = 0
def fake_random_code(length=4):
    global START_SEED
    START_SEED += 1
    if START_SEED > 9999:
        START_SEED = 1
    return f"{START_SEED:0{length}d}"


def sale_code_generator():
    return f"S{datetime.now().strftime('%Y%m%d%H%M')}{fake_random_code()}"

def match_sale_code(code):
    if not isinstance(code, str):
        return False
    return re.match(r"S\d{4,}", code)

def purchase_code_generator():
    return f"C{datetime.now().strftime('%Y%m%d%H%M')}{fake_random_code()}"

def match_purchase_code(code):
    if not isinstance(code, str):
        return False
    return re.match(r"C\d{4,}", code)


def product_code_generator():
    return f"P{datetime.now().strftime('%Y%m%d%H%M')}{fake_random_code()}"

def match_product_code(code):
    if not isinstance(code, str):
        return False
    return re.match(r"P\d{4,}", code)

def format_datetime(date_time, format_str="%Y-%m-%d %H:%M:%S"):
    if isinstance(date_time, datetime):
        return date_time.strftime(format_str)
    elif isinstance(date_time, str): # 去掉毫秒
        return date_time.split(".")[0]
    else:
        return ""
    
def match_phone_number(phone):
    if not isinstance(phone, str):
        return False
    return re.match(r"^1[3-9]\d{9}$", phone) or re.match(r"^0\d{2,3}?\d{7,8}$", phone)
    
def encrypt_phone(phone):
    if not isinstance(phone, str):
        return ""
    if len(phone) < 10:
        return "****" + phone[-4:]
    else:
        return phone[:3] + "****" + phone[-4:]
    
def encrypt_password(password):
    if not isinstance(password, str):
        return ""
    return hashlib.sha256(password.encode()).hexdigest()

def delayed_return(delay=1000):
    """PySide6中模拟长时间执行
    delay: 延迟时间(毫秒)
    """
    from PySide6.QtCore import QTimer, QEventLoop
    loop = QEventLoop()
    def on_timeout():
        loop.quit()
    QTimer.singleShot(delay, on_timeout)
    loop.exec()